﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using Sistema_Totem.Logica.Excepciones;
using Sistema_Totem.Logica.Clases;


namespace Sistema_Totem.Datos.SqlServer
{
    public class SqlServerCasosDeUso
    {
        private Conexion conexion;

        #region Agregar Caso de Uso

        public int AgregarCasoDeUso(CasoDeUso casodeuso, int idRequerimiento)
        {

            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("fk_requerimiento");
            variables.Add("codigo");
            variables.Add("numero");
            variables.Add("nombre");
            variables.Add("cantidad_secciones");
            valores.Add(idRequerimiento.ToString());
            valores.Add(casodeuso.Codigo);
            valores.Add(casodeuso.Numero.ToString());
            valores.Add(casodeuso.Nombre);
            valores.Add(casodeuso.Secciones.ToString());

            int resultado = EjecutarQuery( "[dbo].[InsertarCasodeUso]", variables, valores);

            return resultado;

        }



        #endregion Agregar Caso de Uso

        #region Eliminar Caso de Uso

        public int EliminarCasoDeUso(int idCasodeUso)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<CasoDeUso> casosuso = new List<CasoDeUso>();

            variables.Add("idCasoUso");
            valores.Add(idCasodeUso.ToString());
            try
            {
                return EjecutarQuery("[dbo].[EliminarCasodeUso]", variables, valores);

            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }

        }

        #endregion Eliminar Caso de Uso

        #region Consultar Caso de Uso

        /// <summary>
        // Consultar los Casos de Uso Activos dado
        // el id del requerimiento.
        /// </summary>

        public List<CasoDeUso> ConsultarCasoDeUso(int idRequerimiento)
        {

            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<CasoDeUso> casosuso = new List<CasoDeUso>();

            variables.Add("idrequerimiento");
            valores.Add(idRequerimiento.ToString());

           
            try
            {
                SqlDataReader reader = BuscarData( "[dbo].[ConsultarCasodeUso]", variables, valores);

                while (reader.Read())
                {
                    CasoDeUso casouso = new CasoDeUso(Convert.ToInt32(reader.GetDecimal(0)), reader.GetString(2), Convert.ToInt32(reader.GetDecimal(3)), reader.GetString(4), Convert.ToInt32(reader.GetDecimal(5)), reader.GetString(7));
                    casosuso.Add(casouso);
                }

                return casosuso;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                Conexion.CerrarConexionBd();
            }
        }


        #endregion Consultar Caso de Uso

        #region Ver Detalle Caso  de Uso

        /// <summary>
        // Consultar los detalles de  un CU
        // suministrado el id  del mismo.
        /// </summary>

        public CasoDeUso DetalleCasodeUso(int idCu)
        {

            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            CasoDeUso casouso = new CasoDeUso();

            variables.Add("idCu");
            valores.Add(idCu.ToString());

          
            try
            {
                SqlDataReader reader = BuscarData("[dbo].[DetalleCu]", variables, valores);

                while (reader.Read())
                {
                                            //               int id,                   String codigo,            int numero,                String nombre,                 int secciones,       String requerimiento)
                    casouso = new CasoDeUso(Convert.ToInt32(reader.GetDecimal(0)),reader.GetString(2),Convert.ToInt32(reader.GetDecimal(3)),reader.GetString(4),Convert.ToInt32(reader.GetDecimal(5)),reader.GetString(7));
                    
                }
                reader.Close();
                return casouso;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                Conexion.CerrarConexionBd();
            }

        }

        #endregion Ver Detalle Caso  de Uso

        #region Plantilla asociada al caso de Uso

        /// <summary>
        // Devuelve el id de la plantilla_proyecto
        // que utiliza  el  caso de uso.
        /// </summary>
        public int PlantillaCasodeUso(int idProyecto)
        {

            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<Seccion> secciones = new List<Seccion>();

            variables.Add("idproyecto");
            valores.Add(idProyecto.ToString());
            int idPlantilla = 0;

           
            try
            {
                SqlDataReader reader = BuscarData( "[dbo].[ConsultarPlantillaCasoDeUso]", variables, valores);

                while (reader.Read())
                {
                    idPlantilla = Convert.ToInt32(reader.GetDecimal(0));
                }
                reader.Close();
                return idPlantilla;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                Conexion.CerrarConexionBd();
            }

        }

        #endregion Plantilla asociada al caso de Uso

        #region Secciones Caso de Uso

        /// <summary>
        // Devuelve las secciones activas 
        // de  una plantilla para el proyecto actual.
        /// </summary>

        public List<Seccion> SeccionesCasodeUso(int idPlantilla)
        {

            
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<Seccion> secciones = new List<Seccion>();

            variables.Add("idplantillaproyecto");
            valores.Add(idPlantilla.ToString());

           
            try
            {
                SqlDataReader reader = BuscarData( "[dbo].[SeccionesPlantilla]", variables, valores);
                
                while (reader.Read())
                {
                    

                    Seccion seccion = new Seccion(Convert.ToInt32(reader.GetDecimal(0)), reader.GetString(2), reader.GetString(3), Convert.ToInt32(reader.GetDecimal(1)), "Estatus", null);
                    secciones.Add(seccion);

                }
                reader.Close();
                return secciones;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                Conexion.CerrarConexionBd();
            }


        }


        #endregion Secciones Caso de Uso

        #region Elementos Seccion

        /// <summary>
        // Devuelve los elementos activos 
        // de  una seccion para el proyecto actual.
        /// </summary>

        public List<Elemento> ElementosSeccion(int idSeccion)
        {


            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<Elemento> elementos = new List<Elemento>();

            variables.Add("idseccion");
            valores.Add(idSeccion.ToString());

          
            try
            {
                SqlDataReader reader = BuscarData( "[dbo].[ElementosSeccion]", variables, valores);
                int posicion = 0;
                while (reader.Read())
                {
                    int idElemento = Convert.ToInt32(reader.GetDecimal(0));
                   
                    Elemento elemento = new Elemento(idElemento,reader.GetString(5),posicion);
                    elementos.Add(elemento);
                    posicion++;

                  
                }

                return elementos;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                Conexion.CerrarConexionBd();
            }


        }


        #endregion Elementos Seccion
        
        #region Valor del Elemento
        
        /// <summary>
        // Devuelve el valor del elemento  
        //para el caso de uso actual.
        /// </summary>

        public String ValorElemento(int idplantilla,int idcasouso)
        {
            String valor = "";

                Conexion miConexion = new Conexion();
                SqlCommand command = new SqlCommand();
                try {
                        miConexion.AbrirConexionBd();
                        command.Connection = miConexion.ObjetoConexion();
                        command.CommandType = CommandType.StoredProcedure;
                        command.CommandText = "[dbo].[ValorElemento]"; //Nombre del StoreProcedure "consultarTodosInvolucrado"

                        command.CommandTimeout = 10;

                        command.Parameters.AddWithValue("@idplantilla", idplantilla);
                        command.Parameters.AddWithValue("@idcasouso", idcasouso);   
                        SqlDataReader reader = command.ExecuteReader();

                        if (reader.Read())
                        {

                            valor = reader.GetString(0);
                           
                        }
                        reader.Close();
                   } 
                   catch (SqlException error)
                   {
                       throw (new Exception("Error en la conexion: " + error));
                   }
                   catch (NullReferenceException error)
                   {
                        throw (new Exception( "Los valores que devuelven la consulta son null", error ));
                   }
                    //se cierra la conexion independientemente de que se haya detectado o no una excepcion.
                   finally
                   {
                        miConexion.CerrarConexionBd();
                   }
                
               

            return valor;
        }
        #endregion Valor del Elemento

        #region Plantilla Proyecto Elemento

        /// <summary>
        // Devuelve el id de PlantillaProyectoElemento
        // asociado al elemento.
        /// </summary>

        public int PlantillaProyectoElemento(int idElemento, int idProyecto)
        {
            int id = -1;
            int idPlantillaProyecto = PlantillaCasodeUso(idProyecto);
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            
            variables.Add("idElemento");
            variables.Add("idPlantillaProyecto");
            valores.Add(idElemento.ToString());
            valores.Add(idPlantillaProyecto.ToString());

           
            try
            {
                SqlDataReader reader = BuscarData( "[dbo].[ElementosActivosProyecto]", variables, valores);

                while (reader.Read())
                {
                    id = Convert.ToInt32(reader.GetDecimal(1));

                }
                reader.Close();
                return id;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                Conexion.CerrarConexionBd();
               
            }
            
        }


        #endregion Plantilla Proyecto Elemento

        #region Consultar Todos los Casos de Uso

        /// <summary>
        // Consultar todos los  Casos de Uso dado
        // el id del proyecto.
        /// </summary>

        public List<CasoDeUso> ConsultarTodosCasosDeUso(int idProyecto)
        {

            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<CasoDeUso> casosuso = new List<CasoDeUso>();

            variables.Add("idproyecto");
            valores.Add(idProyecto.ToString());

            try
            {
                SqlDataReader reader = BuscarData( "[dbo].[ConsultarCasosdeUsoProyecto]", variables, valores);

                while (reader.Read())
                {
                    CasoDeUso casouso = new CasoDeUso(Convert.ToInt32(reader.GetDecimal(0)), reader.GetString(2), Convert.ToInt32(reader.GetDecimal(3)), reader.GetString(4), Convert.ToInt32(reader.GetDecimal(5)), reader.GetString(7));
                    casosuso.Add(casouso);
                }
                reader.Close();
                return casosuso;
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }
            finally
            {

                Conexion.CerrarConexionBd();
            }
        }


        #endregion Consultar Todos los Casos de Uso

        #region Editar Caso de Uso

        #endregion Editar Caso de Uso

      

        #region Buscar Data

        /// <summary>
        /// Metodo encargado de invocar a los stored
        /// procedures para realizar transacciones de
        /// consulta.
        /// Devuelve SqlDataReader si se realizo la operacion
        /// efectivamente.
        /// Los metodos que invoquen a este metodo deben cerrar
        /// la conexion luego de leer la data, ya que si se cierra
        /// aqui no se puede ejecutar el reader.
        /// </summary>

        public SqlDataReader BuscarData(String nombreProcedure, List<String> variablesProcedure, List<String> valoresVariables)
        {


            SqlCommand comando = new SqlCommand();
            SqlDataReader lector = null;
            if (Conexion == null)
            {
                Conexion = new Conexion();
            }
            else
            {
                Conexion.CerrarConexionBd();
            }
            try
            {
                //se abre una conexion a base de datos
                
                Conexion.AbrirConexionBd();
                
                //se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure
                comando.Connection = Conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;
                //variables del stored procedure de sql server
                int i = 0;
                while (i < variablesProcedure.Count())
                {

                    comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                    comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;
                   
                    i++;
                }
                //se ejecuta el comando
    
                lector = comando.ExecuteReader();
                
                return lector;
                
            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }



        }


        #endregion Buscar Data

        #region Ejecutar Query

        /// <summary>
        /// Metodo encargado de invocar a los stored
        /// procedures para realizar transacciones de
        /// insercion,modificacion y eliminacion.
        /// Devuelve int 1 si se realizo la operacion
        /// efectivamente.
        /// </summary>

        public int EjecutarQuery(String nombreProcedure, List<String> variablesProcedure, List<String> valoresVariables)
        {

            Conexion = new Conexion();
            SqlCommand comando = new SqlCommand();

            try
            {
                //se abre una conexion a base de datos
                Conexion.AbrirConexionBd();
                //se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure
                comando.Connection = conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;
                //variables del stored procedure de sql server
                int i = 0;
                while (i < variablesProcedure.Count())
                {

                    comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                    comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;

                    i++;
                }
                //se ejecuta el comando
                comando.ExecuteScalar();
                return 1;


            }
            catch (ErrorConexionException)
            {
                throw new ErrorConexionException();


            }
            catch (Exception)
            {
                throw new Exception();
            }

            finally
            {
                Conexion.CerrarConexionBd();

            }

        }


        #endregion Ejecutar Query



        public Conexion Conexion
        {
            get { return conexion; }
            set { conexion= value; }
        }



    }
}